use serde::Serialize;
use sysinfo::{CpuExt, DiskExt, System, SystemExt};

#[derive(Debug, Serialize, Clone)]
pub struct SystemStats {
    pub cpu_usage: f32,
    pub memory_usage: MemoryStats,
    pub disk_usage: Vec<DiskStats>,
}

#[derive(Debug, Serialize, Clone)]
pub struct MemoryStats {
    pub total: u64,
    pub used: u64,
    pub used_percent: f32,
}

#[derive(Debug, Serialize, Clone)]
pub struct DiskStats {
    pub name: String,
    pub total: u64,
    pub used: u64,
    pub used_percent: f32,
}

pub fn collect_system_stats() -> SystemStats {
    let mut sys = System::new_all();
    sys.refresh_all();

    let cpu_usage = if sys.cpus().is_empty() {
        0.0
    } else {
        let total: f32 = sys.cpus().iter().map(|c| c.cpu_usage()).sum();
        total / sys.cpus().len() as f32
    };

    let total_memory = sys.total_memory();
    let used_memory = sys.used_memory();
    let memory_usage = MemoryStats {
        total: total_memory,
        used: used_memory,
        used_percent: if total_memory == 0 {
            0.0
        } else {
            used_memory as f32 / total_memory as f32 * 100.0
        },
    };

    let disk_usage = sys
        .disks()
        .iter()
        .map(|disk| {
            let total = disk.total_space();
            let used = total.saturating_sub(disk.available_space());
            DiskStats {
                name: disk.name().to_string_lossy().into_owned(),
                total,
                used,
                used_percent: if total == 0 {
                    0.0
                } else {
                    used as f32 / total as f32 * 100.0
                },
            }
        })
        .collect();

    SystemStats {
        cpu_usage,
        memory_usage,
        disk_usage,
    }
}
